// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// S [author] rhyme_lph
// I [email]  rhymelph@gmail.com
// M [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/app_colors.dart';
import 'package:finance_app/src/common/app_spaces.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/bill_entity.dart';
import 'package:finance_app/src/entities/debit_note_detail_entity.dart';
import 'package:finance_app/src/entities/format/service_and_product_entity.dart';
import 'package:finance_app/src/entities/ocr_attachment_entity.dart';
import 'package:finance_app/src/entities/setting_data_entity.dart';
import 'package:finance_app/src/entities/transaction_entity.dart';
import 'package:finance_app/src/provider/dashboard/contact/business_contact_detail_provider.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/utils/cash_utils.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/utils/object_utils.dart';
import 'package:finance_app/src/widgets/button/normal_border_button.dart';
import 'package:finance_app/src/widgets/button/normal_popup_button.dart';
import 'package:finance_app/src/widgets/button/normal_text_button.dart';
import 'package:finance_app/src/widgets/common_app_bar.dart';
import 'package:finance_app/src/widgets/form/add_form.dart';
import 'package:finance_app/src/widgets/form/attach_file_form.dart';
import 'package:finance_app/src/widgets/form/currency_gst_amount_form_item.dart';
import 'package:finance_app/src/widgets/form/form_edit_status_inherited_widget.dart';
import 'package:finance_app/src/widgets/form/price_form.dart';
import 'package:finance_app/src/widgets/form/service_and_product_form_item.dart';
import 'package:finance_app/src/widgets/form/text_area_input_form.dart';
import 'package:finance_app/src/widgets/form/value_select_form.dart';
import 'package:finance_app/src/widgets/input/form_input_field.dart';
import 'package:finance_app/src/widgets/wrapper/normal_form_wrapper.dart';
import 'package:flutter/material.dart';
import 'package:finance_app/src/provider/dashboard/debit_note/new_debit_note_provider.dart';
import 'package:finance_app/src/router_gen/router_meta.dart';
import 'package:tuple/tuple.dart';

@RouterMeta(paramName: "newDebitNotePage")
class NewDebitNotePage extends StatefulWidget {
  final TransactionEntity data;
  final bool isSelectMode;

  const NewDebitNotePage({Key key, this.data, this.isSelectMode})
      : super(key: key);

  @override
  _NewDebitNotePageState createState() => _NewDebitNotePageState();
}

class _NewDebitNotePageState extends State<NewDebitNotePage>
    with PagePresenter<NewDebitNotePage, NewDebitNoteProvider> {
  String get title => provider.data == null && pageStatus != PageStatus.loading
      ? S.current.new_debit_note
      : provider.isEdit == true
          ? S.current.edit_debit_note
          : S.current.debit_note;

  Widget get rightButton => listBuilder<bool>(
        selector: (_, __) => __.isEdit == false && __.data != null,
        builder: (BuildContext context, bool value, Widget child) =>
            value ? _buildPopButton() : _buildSaveBtn(),
      );

  @override
  PreferredSizeWidget get appBar => getDefaultAppBar(
          titleWidget: listBuilder<Tuple2<DebitNoteDetailEntity, bool>>(
            selector: (_, __) => Tuple2(__.data, __.isEdit),
            builder: (BuildContext context,
                    Tuple2<DebitNoteDetailEntity, bool> value, Widget child) =>
                Text(title),
          ),
          actions: [
            rightButton,
          ]);

  Widget _buildPopButton() => listBuilder<Tuple2<bool, List<String>>>(
        selector: (_, __) => Tuple2(__.isEdit == true, List.from(__.menuList)),
        builder: (BuildContext context, Tuple2<bool, List<String>> value,
                Widget child) =>
            value.item1 == true
                ? Container()
                : NormalMorePopupButton(
                    onSelect: provider.onSelectMenu,
                    menuList: provider.menuList,
                  ),
      );

  Widget _buildSaveBtn() {
    return listBuilder<bool>(
      selector: (_, __) => pageStatus != PageStatus.loading,
      builder: (BuildContext context, bool value, Widget child) => value == true
          ? NormalSaveTextButton(
              onTap: provider.onSave,
            )
          : Container(),
    );
  }

  @override
  void initState() {
    provider.init(widget.data?.transactionableId);
    final detail = Providers.get<BusinessContactDetailProvider>(
        RouterGenProviders.businessContactDetailPage, null);
    if (detail != null) {
      provider.issueTo = detail.contact;
    }
    super.initState();
  }

  @override
  Widget wrapperBody(Widget child) {
    return listBuilder<bool>(
      selector: (_, __) => __.isEdit == true || provider.id == null,
      builder: (BuildContext context, bool value, Widget child) =>
          FormEditStatusInheritedWidget(
        isEdit: value,
        child: child,
      ),
      child: child,
    );
  }

  @override
  Widget get buildWidget => ListView(
        children: [
          FromInputField(
            controller: provider.debitNoteController,
            focusNode: provider.debitNoteFocusNode,
            tip: S.current.debit_note_number,
          ),
          listBuilder<DateTime>(
            selector: (_, __) => __.date,
            builder: (BuildContext context, DateTime value, Widget child) =>
                ValueSelectForm(
              title: S.current.issue_date,
              value: ObjectUtils.isNullDefaultFormat<DateTime>(value, null,
                  (data) => DateTimeUtils.formatGlobalDateTime(data)),
              onTap: provider.onChangeIssueDate,
            ),
          ),
          listBuilder<String>(
            selector: (_, __) => __.issueTo?.name,
            builder: (BuildContext context, String value, Widget child) =>
                ValueSelectForm(
              title: S.current.issue_to,
              value: value,
              onTap: provider.onChangeIssueTo,
            ),
          ),
          listBuilder<String>(
            selector: (_, __) => __.billNumber?.number,
            builder: (BuildContext context, String value, Widget child) =>
                ValueSelectForm(
              title: S.current.bill_number,
              value: value == null || value.isEmpty ? null : value,
              onTap: provider.onChangeBillNumber,
            ),
          ),
          listBuilder<BillEntity>(
            selector: (_, __) => __.billNumber,
            builder: (BuildContext context, BillEntity value, Widget child) =>
                value != null
                    ? Column(
                        children: [
                          listBuilder<int>(
                            selector: (_, __) =>
                                List<ServiceAndProductEntity>.from(
                                        __.serviceAndProductList)
                                    .length,
                            builder: (BuildContext context, int value,
                                    Widget child) =>
                                value != 0
                                    ? Column(
                                        children: [
                                          ...List.generate(
                                              value,
                                              (index) => listBuilder<
                                                      Tuple4<
                                                          ServiceAndProductEntity,
                                                          int,
                                                          num,
                                                          SettingDataTax>>(
                                                    selector: (_, __) => Tuple4(
                                                        __.serviceAndProductList[
                                                            index],
                                                        __
                                                            .serviceAndProductList[
                                                                index]
                                                            .number,
                                                        __
                                                            .serviceAndProductList[
                                                                index]
                                                            .discountedAmount,
                                                        __
                                                            .serviceAndProductList[
                                                                index]
                                                            .tax),
                                                    builder: (BuildContext
                                                                context,
                                                            Tuple4<
                                                                    ServiceAndProductEntity,
                                                                    int,
                                                                    num,
                                                                    SettingDataTax>
                                                                value,
                                                            Widget child) =>
                                                        ServiceAndProductFormItem(
                                                      onTap: () =>
                                                          provider.onSelectItem(
                                                              value.item1),
                                                      productEntity:
                                                          value.item1,
                                                      hasError: false,
                                                      showHeader: index == 0,
                                                      isLastElement: provider
                                                                  .serviceAndProductList
                                                                  .length ==
                                                              index + 1 &&
                                                          provider.id != null &&
                                                          provider.isEdit ==
                                                              false,
                                                    ),
                                                  ))
                                        ],
                                      )
                                    : ValueSelectForm(
                                        title: 'Item & Debit Amount',
                                        onTap: provider.onAddItem,
                                      ),
                          ),
                          AddForm(
                            title: S.current.add_item,
                            onTap: provider.onAddItem,
                          ),
                        ],
                      )
                    : Container(),
          ),
          AppSpaces.grayH6,
          NormalFormWrapper(
            child: listBuilder<bool>(
              selector: (_, __) => __.id != null,
              builder: (BuildContext context, bool value, Widget child) => value
                  ? Column(
                      children: [
                        listBuilder<num>(
                          selector: (_, __) => __.data.total,
                          builder:
                              (BuildContext context, num value, Widget child) =>
                                  PriceForm(
                            title: S.current.subtotal,
                            amount: CashUtils.formatCashAmount(value),
                          ),
                        ),
                        buildIncludes(),
                        AppSpaces.h20,
                        listBuilder<num>(
                          selector: (_, __) =>
                              __.data.total - __.data.refundTotal,
                          builder:
                              (BuildContext context, num value, Widget child) =>
                                  PriceForm(
                            title: S.current.credit,
                            amount: CashUtils.formatCashAmount(-value),
                          ),
                        ),
                        AppSpaces.h20,
                        listBuilder<num>(
                          selector: (_, __) => __.data.refundTotal,
                          builder:
                              (BuildContext context, num value, Widget child) =>
                                  PriceForm(
                            title: S.current.refund,
                            amount: CashUtils.formatCashAmount(-value),
                          ),
                        ),
                        AppSpaces.h20,
                        listBuilder<num>(
                          selector: (_, __) => __.data.unpaid,
                          builder:
                              (BuildContext context, num value, Widget child) =>
                                  PriceForm(
                            title: S.current.balance,
                            amount: CashUtils.formatCashAmount(value),
                          ),
                        ),
                      ],
                    )
                  : listBuilder<num>(
                      selector: (_, __) => __.total,
                      builder:
                          (BuildContext context, num value, Widget child) =>
                              PriceForm(
                        title: S.current.total,
                        amount: CashUtils.formatCashAmount(value),
                      ),
                    ),
            ),
          ),
          AppSpaces.grayH6,
          TextAreaInputForm(
            title: S.current.reasons_optional,
            controller: provider.notesController,
            focusNode: provider.notesFocusNode,
          ),
          NormalFormWrapper(
            child: listBuilder<Tuple2<List<String>, List<OcrAttachmentEntity>>>(
              selector: (_, __) =>
                  Tuple2(List.from(__.files), List.from(__.attachments ?? [])),
              builder: (BuildContext context,
                      Tuple2<List<String>, List<OcrAttachmentEntity>> value,
                      Widget child) =>
                  AttachFileForm(
                onAdd: provider.onAddAttachment,
                files: value.item1,
                onSelectFile: provider.onSelectFile,
                attachments: value.item2,
                onSelectAttachment: provider.onSelectAttachment,
              ),
            ),
          ),
          AppSpaces.h30,
          FormStatusWidget(
            enable: Container(),
            disable: Column(
              children: [
                listBuilder<bool>(
                  selector: (_, __) => __.menuList.contains('Receive Refund'),
                  builder: (BuildContext context, bool value, Widget child) =>
                      value
                          ? Column(
                              children: [
                                NormalBorderButton(
                                  title: S.current.receive_refund,
                                  onTap: provider.onReceiveRefund,
                                  isFit: true,
                                ),
                                AppSpaces.h30,
                              ],
                            )
                          : Container(),
                ),
                listBuilder<bool>(
                  selector: (_, __) => __.menuList.contains('Keep As Credit'),
                  builder: (BuildContext context, bool value, Widget child) =>
                      value
                          ? Column(
                              children: [
                                NormalBorderButton(
                                  title: S.current.keep_as_credit,
                                  onTap: provider.onKeepAsCredit,
                                  isFit: true,
                                ),
                                AppSpaces.h30,
                              ],
                            )
                          : Container(),
                ),
                listBuilder<bool>(
                  selector: (_, __) => __.menuList.contains('See Payment'),
                  builder: (BuildContext context, bool value, Widget child) =>
                      value
                          ? Column(
                              children: [
                                NormalBorderButton(
                                  title: S.current.see_payment,
                                  onTap: provider.onSeePayment,
                                  isFit: true,
                                ),
                                AppSpaces.h30,
                              ],
                            )
                          : Container(),
                ),
              ],
            ),
          )
        ],
      );

  Widget buildIncludes() {
    return Align(
      alignment: Alignment.centerRight,
      child: Config.currentCompany.enableGst == 0
          ? Container()
          : Container(
              padding: EdgeInsets.only(top: 2),
              child: listBuilder<double>(
                  builder: (BuildContext context, double value, Widget child) =>
                      Text(
                        '${S.current.includes_gst} ${CashUtils.formatCashAmount(value)}',
                        style: TextStyle(
                          color: aceDarkGrayColor,
                          fontSize: getSp(14),
                          fontWeight: FontWeight.w400,
                          height: 1,
                        ),
                      ),
                  selector: (_, __) => __.includesGST + __.gst),
            ),
    );
  }
}
